package com.demo.modules.sys.service.impl;

import com.demo.common.constant.Constant;
import com.demo.common.enums.TokenTypeEnum;
import com.demo.common.exception.RRException;
import com.demo.modules.sys.dao.SysMenuDao;
import com.demo.modules.sys.dao.SysUserDao;
import com.demo.modules.sys.entity.SysMenuEntity;
import com.demo.modules.sys.entity.SysUserEntity;
import com.demo.modules.sys.form.SysLoginForm;
import com.demo.modules.sys.service.*;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author Zsx
 */
@Service("shiroService")
@AllArgsConstructor
public class ShiroServiceImpl implements ShiroService {

    private final SysCaptchaService sysCaptchaService;
    private final SysUserService sysUserService;
    private final SysMenuDao sysMenuDao;
    private final SysUserDao sysUserDao;
    private final SysLogService sysLogService;
    private final SysUserRoleService sysUserRoleService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysUserEntity login(SysLoginForm form, String tokenType, String ip) {
        if (TokenTypeEnum.SYS.getValue().equals(tokenType)) {
            boolean captcha = sysCaptchaService.validate(form.getUuid(), form.getCaptcha());
            if (!captcha) {
                throw new RRException("验证码不正确");
            }
        }

        // 自动登录
        boolean rememberMe = false;
        if (TokenTypeEnum.APP.getValue().equals(tokenType)) {
            rememberMe = true;
        }

        AuthenticationToken token = new UsernamePasswordToken(form.getUsername(), form.getPassword(), rememberMe, ip);

        try {
            SecurityUtils.getSubject().login(token);
        } catch (IncorrectCredentialsException e) {
            throw new RRException("密码错误");
        } catch (LockedAccountException e) {
            throw new RRException("登录失败，该用户已被禁用");
        } catch (UnknownAccountException e) {
            throw new RRException("该用户不存在");
        }

        SysUserEntity user = (SysUserEntity) SecurityUtils.getSubject().getPrincipal();

        //获取用户所属的角色列表
        List<Long> roleIdList = sysUserRoleService.queryRoleIdList(user.getId());
        user.setRoleIdList(roleIdList);

        //记录登陆ip及时间
        user.setLastLoginIp(ip);
        user.setLastLoginTime(new Date());
        sysUserService.updateById(user);

        // 记录日志
        sysLogService.saveLog(user.getId(), "用户登录", ip);
        return user;
    }

    @Override
    public Set<String> getUserPermissions(long userId) {
        List<String> permsList;

        //系统管理员，拥有最高权限
        if (userId == Constant.SUPER_ADMIN) {
            List<SysMenuEntity> menuList = sysMenuDao.selectList(null);
            permsList = new ArrayList<>(menuList.size());
            for (SysMenuEntity menu : menuList) {
                permsList.add(menu.getPerms());
            }
        } else {
            permsList = sysUserDao.queryAllPerms(userId);
        }
        //用户权限列表
        Set<String> permsSet = new HashSet<>();
        for (String perms : permsList) {
            if (StringUtils.isBlank(perms)) {
                continue;
            }
            permsSet.addAll(Arrays.asList(perms.trim().split(",")));
        }
        return permsSet;
    }

    @Override
    public SysUserEntity queryUser(Long userId) {
        return sysUserDao.selectById(userId);
    }

    @Override
    public void logout(long userId) {
        SecurityUtils.getSubject().logout();
    }
}
